package com.dingreading.cloud.soms.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.dto.LoginDataDto;
import com.dingreading.cloud.common.dto.StoreProjectsDto;
import com.dingreading.cloud.common.util.*;
import com.dingreading.cloud.soms.dto.StoreProjectsDtoV2;
import com.dingreading.cloud.soms.dto.SubjectsDto;
import com.dingreading.cloud.soms.entity.StoreProjects;
import com.dingreading.cloud.soms.entity.Subjects;
import com.dingreading.cloud.soms.service.*;
import com.dingreading.cloud.soms.util.CmorderUtil;
import com.dingreading.cloud.soms.util.LoginInfoUtil;
import com.dingreading.cloud.soms.util.ProjectCycleUtil;
import com.dingreading.cloud.soms.util.TreeJsonUtil;
import com.dingreading.cloud.soms.util.redis.RedisService;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RestController
@RequestMapping(value = "/front/storeProjects/v3")
@Api(tags = "门店-门店服务管理V3")
public class FrontStoreProjectsControllerV3 {

    @Resource
    protected StoreProjectsService projectsService;
    @Resource
    protected StoreProductLogsService productLogsService;
    @Resource
    protected CaClassService classService;
    @Resource
    protected CaScheduleLessonService scheduleLessonService;
    @Resource
    protected StoresService storesService;
    @Resource
    protected CmservicesService cmservicesService;
    @Resource
    protected StoreProjectCycleService cycleService;
    @Resource
    protected StoreProjectStageService stageService;
    @Resource
    private SubjectsService subjectsService;
    @Resource
    protected RedisService redisService;


    @ApiOperation(value = "门店服务分页列表")
    @PostMapping(value = "/pageList", produces = "application/json; charset=UTF-8")
    public R<Object> pageList(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "服务名称") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "活动状态 1.可排活动 0.不可排活动") @RequestParam(value = "lessonStatus", required = false) Integer lessonStatus,
            @ApiParam(value = "活动次数状态 1.消耗次数 0.免费") @RequestParam(value = "freeStatus", required = false) Integer freeStatus,
            @ApiParam(value = "启用状态") @RequestParam(value = "enabled", required = false) Integer enabled
    ) {
        // 获取门店的服务
        List<Long> projectIdList = storesService.getProjectIdList(storeUid);
        if (CollectionUtils.isEmpty(projectIdList))
            return R.fail("门店未分配服务，请联系运营人员");

        Page<StoreProjectsDto> page = projectsService.storeProjectPageV5(
                pageUtil, storeUid, keyword, lessonStatus, freeStatus, enabled, projectIdList
        );

        PageBeanDto dto = new PageBeanDto();
        dto.setTotal(page.getTotalRow());
        dto.setList(page.getRecords());

        return R.ok(dto);
    }


    @ApiOperation(value = "获取信息")
    @PostMapping(value = "/getBean", produces = "application/json; charset=UTF-8")
    public R<Object> getBean(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "服务uid") @RequestParam(value = "uid") String uid
    ) {
        StoreProjectsDto data = projectsService.getDtoByUid(uid);
        if (null == data)
            return R.fail("获取失败");

        return R.ok(data);
    }

    @Transactional(rollbackFor = DescribeException.class)
    @ApiOperation(value = "创建/编辑信息")
    @PostMapping(value = "/newBean", produces = "application/json; charset=UTF-8")
    public R<Object> newBean(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "服务uid") @RequestParam(value = "uid", required = false) String uid,
            @ApiParam(value = "服务名称") @RequestParam(value = "projectName") String projectName,
            @ApiParam(value = "活动状态 1.可排活动 0.不可排活动") @RequestParam(value = "lessonStatus") Integer lessonStatus,
            @ApiParam(value = "活动次数状态 1.消耗次数 0.不消耗次数") @RequestParam(value = "freeStatus", required = false) Integer freeStatus,
            @ApiParam(value = "备注") @RequestParam(value = "remark", required = false) String remark
    ) {
        R<Object> r = LoginInfoUtil.getLoginDto(request);
        if (R.isError(r)) return r;
        LoginDataDto loginDto = (LoginDataDto) r.getData();

        boolean selfStore = AccountUtil.isSelfStore(loginDto.getCurrentOperationType());

        boolean b = projectsService.haveNameV2(storeUid, uid, projectName);
        if (b)
            return R.fail("服务名称重复了");

        if (StringUtils.isBlank(uid)) {
            // 创建
            // 获取最大的主渠道展示序号
            int maxOrderNum = projectsService.getMaxOrderNum(storeUid) + 1;

            int source = 0;
            if (selfStore) {
                source = 2;
            } else {
                source = 2;
            }

            StoreProjects data = ProjectCycleUtil.newProject(
                    storeUid, storeName, projectName, lessonStatus, freeStatus, maxOrderNum, source,
                    remark, staffUid, staffName, null
            );
            projectsService.saveOrUpdate(data);
        } else {
            // 编辑
            StoreProjects data = projectsService.getByStoreUidAndUid(storeUid, uid);
            if (null == data)
                return R.fail("服务获取失败");
            if (!data.getSource().equals(2))
                return R.fail("非门店数据，不能操作");

            // 判断服务是否被使用
            if (!data.getProjectName().equals(projectName)) {
                String msg = useProject(storeUid, uid);
                if (StringUtils.isNotBlank(msg))
                    return R.fail(msg);
            }

            b = projectsService.updateInfoV2(storeUid, uid, projectName, staffUid, staffName);
            if (!b)
                return R.fail("更新失败");
        }

        // 清除门店服务周期缓存数据
        redisService.setNullLike(RedisParam.PROJECT_CYCLE + storeUid);

        return R.ok();
    }


    @ApiOperation(value = "删除信息")
    @PostMapping(value = "/dropBean", produces = "application/json; charset=UTF-8")
    public R<Object> dropBean(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "服务uid") @RequestParam(value = "uid") String uid
    ) {
        StoreProjects data = projectsService.getByStoreUidAndUid(storeUid, uid);
        if (null == data)
            return R.fail("获取失败");
        if (!data.getSource().equals(2))
            return R.fail("非门店数据，不能操作");

        // 判断服务是否被使用
        String msg = useProject(storeUid, uid);
        if (StringUtils.isNotBlank(msg))
            return R.fail(msg);

        long i = projectsService.dropBean(storeUid, uid);
        if (i <= 0)
            return R.fail("删除失败");

        cycleService.dropByProjectUid(storeUid, uid);
        stageService.dropByProjectUid(storeUid, uid);

        // 清除门店服务周期缓存数据
        redisService.setNullLike(RedisParam.PROJECT_CYCLE + storeUid);

        return R.ok();
    }


    @ApiOperation(value = "更新启用状态")
    @PostMapping(value = "/updateEnabled", produces = "application/json; charset=UTF-8")
    public R<Object> updateEnabled(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "服务uid") @RequestParam(value = "uid") String uid,
            @ApiParam(value = "是否禁用 1.启用 0.禁用") @RequestParam(value = "enabled") Integer enabled
    ) {
        StoreProjects data = projectsService.getByStoreUidAndUid(storeUid, uid);
        if (null == data)
            return R.fail("获取失败");
        if (!data.getSource().equals(2))
            return R.fail("非门店数据，不能操作");

        boolean l = projectsService.updateEnabledV2(storeUid, uid, enabled, staffUid, staffName);
        if (!l)
            return R.fail("更新服务状态失败");

        // 清除门店服务周期缓存数据
        redisService.setNullLike(RedisParam.PROJECT_CYCLE + storeUid);

        return R.ok();
    }


    @ApiOperation(value = "上移/下移")
    @PostMapping(value = "/upOrDown", produces = "application/json; charset=UTF-8")
    public R<Object> upOrDown(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "服务uid") @RequestParam(value = "uid") String uid,
            @ApiParam(value = "类型 1.上移 2.下移") @RequestParam(value = "type") Integer type
    ) {
        StoreProjects data = projectsService.getByStoreUidAndUid(storeUid, uid);
        if (null == data)
            return R.fail("获取失败");
        if (!data.getSource().equals(2))
            return R.fail("非门店数据，不能操作");

        if (type.equals(1)) {
            // 上移
            StoreProjects preData = projectsService.getLtShowOrder(storeUid, data.getOrderNum());
            if (preData == null)
                return R.fail("已在最前");
            // 和前一条记录的序号互换
            Integer prevOrderNum = preData.getOrderNum();
            Integer curOrderNum = data.getOrderNum();
            // 序号互换
            projectsService.updateOrderNum(storeUid, preData.getUid(), curOrderNum, staffUid, staffName);
            projectsService.updateOrderNum(storeUid, data.getUid(), prevOrderNum, staffUid, staffName);
        } else if (type.equals(2)) {
            // 下移
            StoreProjects backData = projectsService.getGtShowOrder(storeUid, data.getOrderNum());
            if (backData == null)
                return R.fail("已在最后");
            // 和后一条记录的序号互换
            Integer backOrderNum = backData.getOrderNum();
            Integer curOrderNum = data.getOrderNum();
            // 序号互换
            projectsService.updateOrderNum(storeUid, backData.getUid(), curOrderNum, staffUid, staffName);
            projectsService.updateOrderNum(storeUid, data.getUid(), backOrderNum, staffUid, staffName);
        } else {
            return R.fail("类型错误");
        }

        // 清除门店服务周期缓存数据
        redisService.setNullLike(RedisParam.PROJECT_CYCLE + storeUid);

        return R.ok();
    }


    @ApiOperation(value = "获取总部和门店的可用服务")
    @PostMapping(value = "/getList", produces = "application/json; charset=UTF-8")
    public R<Object> getList(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "服务名称") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "活动状态 1.可排活动 0.不可排活动") @RequestParam(value = "lessonStatus", required = false) Integer lessonStatus
    ) {
        // 获取门店的服务
        List<Long> projectIdList = storesService.getProjectIdList(storeUid);
        if (CollectionUtils.isEmpty(projectIdList))
            return R.fail("门店未分配服务，请联系运营人员");

        List<StoreProjectsDtoV2> list = projectsService.dtoListByStoreUidAndSelfStoreV5(
                storeUid, keyword, lessonStatus, null, projectIdList
        );
        return R.ok(list);
    }


    @ApiOperation(value = "社团-获取总部和门店的可用服务")
    @PostMapping(value = "/getListByClass", produces = "application/json; charset=UTF-8")
    public R<Object> getListByClass(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "服务名称") @RequestParam(value = "keyword", required = false) String keyword
    ) {
        R<Object> r = LoginInfoUtil.getLoginDto(request);
        if (R.isError(r)) return r;
        LoginDataDto loginDto = (LoginDataDto) r.getData();

        boolean selfStore = AccountUtil.isSelfStore(loginDto.getCurrentOperationType());

        // 获取门店的服务
        List<Long> projectIdList = storesService.getProjectIdList(storeUid);
        if (CollectionUtils.isEmpty(projectIdList))
            return R.fail("门店未分配服务，请联系运营人员");

        List<StoreProjectsDtoV2> list = projectsService.dtoListByStoreUidAndSelfStoreV5(
                storeUid, keyword, 1, null, projectIdList
        );

        // 设置阶段并禁用没有周期的服务
        List<StoreProjectsDtoV2> newList = CmorderUtil.setStageList(selfStore, storeUid, list);

        return R.ok(newList);
    }


    @ApiOperation(value = "产品-获取总部和门店的可用收费服务")
    @PostMapping(value = "/getListByProduct", produces = "application/json; charset=UTF-8")
    public R<Object> getListByProduct(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "服务名称") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "活动状态 1.可排活动 0.不可排活动") @RequestParam(value = "lessonStatus", required = false) Integer lessonStatus
    ) {
        R<Object> r = LoginInfoUtil.getLoginDto(request);
        if (R.isError(r)) return r;
        LoginDataDto loginDto = (LoginDataDto) r.getData();

        boolean selfStore = AccountUtil.isSelfStore(loginDto.getCurrentOperationType());

        // 获取门店的服务
        List<Long> projectIdList = storesService.getProjectIdList(storeUid);
        if (CollectionUtils.isEmpty(projectIdList))
            return R.fail("门店未分配服务，请联系运营人员");

        List<StoreProjectsDtoV2> list = projectsService.dtoListByStoreUidAndSelfStoreV5(
                storeUid, keyword, lessonStatus, null, projectIdList
        );

        // 设置周期并禁用没有周期的服务
        List<StoreProjectsDtoV2> newList = CmorderUtil.setCycleList(selfStore, storeUid, list);

        return R.ok(newList);
    }


    @ApiOperation(value = "获取基础收费服务和周期")
    @PostMapping(value = "/getProjectAndCycleList", produces = "application/json; charset=UTF-8")
    public R<Object> getProjectAndCycleList(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName
    ) {
        R<Object> r = LoginInfoUtil.getLoginDto(request);
        if (R.isError(r)) return r;
        LoginDataDto loginDto = (LoginDataDto) r.getData();

        boolean selfStore = AccountUtil.isSelfStore(loginDto.getCurrentOperationType());

        // 获取门店的服务
        List<Long> projectIdList = storesService.getProjectIdList(storeUid);
        if (CollectionUtils.isEmpty(projectIdList))
            return R.fail("门店未分配服务，请联系运营人员");

        // redis取值
        String redisKey = RedisParam.PROJECT_CYCLE + storeUid;
        String json = (String) redisService.get(redisKey);
        if (StringUtils.isNotBlank(json)) {
            List<StoreProjectsDtoV2> list = JSONArray.parseArray(json, StoreProjectsDtoV2.class);
            return R.ok(list);
        } else {
            List<StoreProjectsDtoV2> list = projectsService.dtoListByStoreUidAndSelfStoreV5(
                    storeUid, null, null, null, projectIdList
            );
            // 设置周期并禁用没有周期的服务
            List<StoreProjectsDtoV2> newList = CmorderUtil.setCycleList(selfStore, storeUid, list);
            // redis缓存
            redisService.set(redisKey, JsonUtil.toJsonString(newList), RedisParam.HOUR_TIME);

            return R.ok(newList);
        }
    }

    @ApiOperation(value = "获取服务激活列表")
    @PostMapping(value = "/getActivationList", produces = "application/json; charset=UTF-8")
    public R<Object> getActivationList(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "服务uid") @RequestParam(value = "projectUid") String projectUid
    ) {
        if (StringUtils.isBlank(projectUid))
            return R.fail("请选择服务");
        if (StringUtils.isBlank(corpUid) || StringUtils.isBlank(storeUid) || StringUtils.isBlank(staffUid))
            return R.fail("请选择门店");
        JSONObject jsonObject = new JSONObject();

        StoreProjects storeProjects = projectsService.getByUid(projectUid);
        if (storeProjects == null)
            return R.fail("服务不存在");
        if (storeProjects.getIsPay() == null)
            return R.fail("服务激活状态未设置！");
        if (storeProjects.getIsPay() == 0){
            jsonObject.put("payStatus", false);
            jsonObject.put("subjects", null);
            return R.ok(jsonObject);
        }
        String subjectUid = storeProjects.getSubjectUid();
        if (StringUtils.isBlank(subjectUid))
            return R.fail("服务未设置科目");

        Subjects subjects = subjectsService.getByUid(subjectUid);
        if (subjects == null)
            return R.fail("科目不存在");
        if (subjects.getSubjectMainId() == null)
            return R.fail("主学科不存在");
        List<SubjectsDto> subjectsList = subjectsService.getBySubjectMainId(subjects.getSubjectMainId());
        if (CollectionUtils.isEmpty(subjectsList))
            return R.fail("主学科分类不存在");
        JSONArray treeJson = TreeJsonUtil.createTreeJson(subjectsList);
        jsonObject.put("payStatus", true);
        jsonObject.put("subjects", treeJson);
        return R.ok(jsonObject);

    }

    /**
     * 判断服务是否被使用
     */
    private String useProject(String storeUid, String projectUid) {
        boolean b = cmservicesService.haveProjectUid(storeUid, projectUid);
        if (b)
            return "会员订单服务已使用，不能操作";

        // 先判断
        b = classService.haveProjectUid(storeUid, projectUid);
        if (b)
            return "社团已使用，不能操作";

        b = scheduleLessonService.haveProjectUid(storeUid, projectUid);
        if (b)
            return "活动已使用，不能操作";

        // 删除前先判断有没有产品记录
        b = productLogsService.haveProjectUid(storeUid, projectUid);
        if (b)
            return "产品包已使用，不能操作";

        return "";
    }

}
